﻿#pragma once

#include "common.h"
#include "ui/ui.h"
#include "ui/panel.h"
#include "ui/button.h"
#include <set>

namespace anip
{
	namespace ui
	{
		class Canvas;

		class ListView : public Control
		{
		public:
			enum class DisplayType
			{
				Icon,
				Detail
			};

			class Header // : public Control
			{
				friend class ListView;

			/*private:
				Header(Container* parent);

			public:
				void paint() override;
				void flow(Flow& f) override;*/
			};

			class Item : public ButtonBase
			{
				friend class ListView;

			private:
				ListView& _list;
				Canvas* _cv;
				vec2 
					_dragPos,
					_dragMouse;

				Item(ListView& parent, const wstring& text);

				void _update();
				int getTextWidth() override;

			protected:
				void processMouseButton(MouseButton btn, ButtonAction action) override;
				bool canBeginDrag(MouseButton btn, invec2 pos) override;
				void processDrag(invec2 start, invec2 pos) override;
				void processEndDrag() override;

			public:
				void setSize(invec2 s) override
				{
					Control::setSize(s);
					_update();
				}

				void select(bool s = true) override;

				void paint() override;
				void flow(Flow& f) override;

				void setImage(const Texture2D* tex);
				const Texture2D* getImage() const;
			};

		private:
			vec2 _itemSize = { 100, 100 };
			DisplayType _type = DisplayType::Icon;
			Scrollable<Panel>* _panel;
			Header* _header;
			std::set<Item*> _selection;

		public:
			ListView(Container* parent = nullptr, invec2 pos = { 0, 0 },
				invec2 size = { 100, 100 });

			Header& header;
			bool allowSelect = true;
			bool allowMultipleSelect = false;
			bool allowDrag = false;

			Item& addItem(const wstring& text = L"");
			//void removeItem(Item& item);
			void clearAllItems();
			Item* firstItem() { return (Item*)(_panel->firstChild()); }
			Item* lastItem() { return (Item*)(_panel->lastChild()); }
			const std::set<Item*> selectedItems() const { return _selection; }
			void clearSelection();

			std::function<void(ListView& self, Item& from, Item& to)> onItemDrag;

			void paint() override;
			//void flow(Flow& f) override;
		};
	}
}